﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Windows.Forms;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Architecture;
using Autodesk.Revit.UI;
using YArchitech.ProgressBar;
using YArchitech.Revit;
using YJKArch.Utils;
using HYCodeBase.WinForm;
using LightingEquipmentLay.Utility;
using RegionSplittor.Data;
using RegionSplittor.Utils;
using RegionSplittor.Utils.ClipPolygon;
using RegionSplittor.Utils.XDataUtils;

namespace LightingEquipmentLay.RegionSearch
{
	public class RegionSearchManager
	{
		public static List<Curve> InitLaneRegionData(Autodesk.Revit.DB.Document doc, Level level)
		{
			return (from e in LightingEquipmentLay.Utility.Common.GetDetailCurvesByExtendName(doc, level, RegionSearchManager.m_strExtendName)
			select e.GeometryCurve).ToList<Curve>();
		}

		public static List<FamilyInstance> InitParkingRegionData(Autodesk.Revit.DB.Document doc, Level level)
		{
			List<FamilyInstance> list = new List<FamilyInstance>();
			ElementCategoryFilter elementCategoryFilter = new ElementCategoryFilter(BuiltInCategory.OST_Parking);
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(doc);
			filteredElementCollector.WherePasses(elementCategoryFilter).WhereElementIsNotElementType();
			foreach (Element element in filteredElementCollector)
			{
				FamilyInstance familyInstance = element as FamilyInstance;
				ElementId elementId = familyInstance.GetParameter(BuiltInParameter.SCHEDULE_LEVEL_PARAM).AsElementId();
				Level level2 = doc.GetElement(elementId) as Level;
				if (level2 != null && RegionSearchManager.IsEqualLevel(level, level2))
				{
					list.Add(familyInstance);
				}
			}
			return list;
		}

		public static List<Room> InitRoomRegionData(Autodesk.Revit.DB.Document doc, Level level)
		{
			List<Room> list = new List<Room>();
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(doc);
			filteredElementCollector.OfCategory(BuiltInCategory.OST_Rooms).WhereElementIsNotElementType();
			foreach (Element element in filteredElementCollector)
			{
				Room room = element as Room;
				if (Math.Abs(room.Area - 0.0) >= 1E-05 && room.Area >= 0.0 && RegionSearchManager.IsEqualLevel(level, room.GetYJKLevel()))
				{
					list.Add(room);
				}
			}
			return list;
		}

		public static List<FamilyInstance> InitColumnData(Autodesk.Revit.DB.Document doc, Level level)
		{
			List<FamilyInstance> list = new List<FamilyInstance>();
			ElementCategoryFilter elementCategoryFilter = new ElementCategoryFilter(BuiltInCategory.OST_StructuralColumns);
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(doc);
			filteredElementCollector.WherePasses(elementCategoryFilter).WhereElementIsNotElementType();
			foreach (Element element in filteredElementCollector)
			{
				FamilyInstance familyInstance = element as FamilyInstance;
				if (RegionSearchManager.IsEqualLevel(level, familyInstance.GetYJKLevel()))
				{
					list.Add(familyInstance);
				}
			}
			return list;
		}

		public static List<Line> InitLinearCombineLaneData(Autodesk.Revit.DB.Document doc, Level level)
		{
			List<Line> list = new List<Line>();
			double projectElevation = level.ProjectElevation;
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(doc);
			filteredElementCollector.OfClass(typeof(CurveElement));
			foreach (Element element in filteredElementCollector)
			{
				DetailCurve detailCurve = element as DetailCurve;
				if (detailCurve != null && !(LaneLineXDataManager.ReadXData(detailCurve) != RegionSearchManager.m_strExtendName))
				{
					Curve geometryCurve = detailCurve.GeometryCurve;
					if (geometryCurve.IsBound)
					{
						XYZ endPoint = geometryCurve.GetEndPoint(0);
						XYZ endPoint2 = geometryCurve.GetEndPoint(1);
						if (Geometry.IsEqual(((endPoint + endPoint2) * 0.5).Z, projectElevation))
						{
							Line line = geometryCurve as Line;
							if (line != null)
							{
								list.Add(line);
							}
							else
							{
								Arc arc = geometryCurve as Arc;
								if (arc != null)
								{
									List<Line> collection = LightingEquipmentLay.Utility.Common.ConvertArc2Lines(arc);
									list.AddRange(collection);
								}
							}
						}
					}
				}
			}
			return LightingEquipmentLay.Utility.Common.CombineEqualLines(list);
		}

		public static List<Grid> InitGridData(Autodesk.Revit.DB.Document doc)
		{
			ElementCategoryFilter elementCategoryFilter = new ElementCategoryFilter(BuiltInCategory.OST_Grids);
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(doc);
			filteredElementCollector.WherePasses(elementCategoryFilter).WhereElementIsNotElementType();
			return filteredElementCollector.Cast<Grid>().ToList<Grid>();
		}

		public static bool IsBeamCellFunctionOnPlane(Level level, List<Curve> lstBoundaryCvs, List<Curve> lstFuncRegionCvs, bool bPlan = false)
		{
			Plane plane = RegionSearchManager.CreatePlaneByLevel(level);
			if (!bPlan)
			{
				foreach (Curve cv in lstBoundaryCvs)
				{
					Curve projectSegCurve = LightingEquipmentLay.Utility.Common.GetProjectSegCurve(plane, cv);
					foreach (Curve cv2 in lstFuncRegionCvs)
					{
						Curve projectSegCurve2 = LightingEquipmentLay.Utility.Common.GetProjectSegCurve(plane, cv2);
						IntersectionResultArray intersectionResultArray = null;
						if ((int)projectSegCurve.Intersect(projectSegCurve2, out intersectionResultArray) == 8 && intersectionResultArray != null)
						{
							return true;
						}
					}
				}
				return false;
			}
			ClipPolygonUtils.DisposeRecordPolygon();
			List<Curve> planeCurve = RegionSearchManager.GetPlaneCurve(plane, lstBoundaryCvs);
			List<Curve> planeCurve2 = RegionSearchManager.GetPlaneCurve(plane, lstFuncRegionCvs);
			MyPolygon item = new MyPolygon(planeCurve);
			List<MyPolygon> list = new List<MyPolygon>();
			list.Add(item);
			MyPolygon convertPolygon = new MyPolygon(planeCurve2);
			if (ClipPolygonUtils.ClipPolygon(list, convertPolygon, AreaClip.Intersection))
			{
				return true;
			}
			return false;
		}

		private static List<Curve> GetPlaneCurve(Plane plane, List<Curve> lstCvs)
		{
			List<Curve> list = new List<Curve>();
			foreach (Curve cv in lstCvs)
			{
				Curve projectSegCurve = LightingEquipmentLay.Utility.Common.GetProjectSegCurve(plane, cv);
				if (null != projectSegCurve)
				{
					list.Add(projectSegCurve);
				}
			}
			return list;
		}

		public static bool IsBeamCellFuncLane(Level level, List<Curve> lstBoundaryCvs, List<Curve> lstLanes, ref RegionFuncInfo regionLane)
		{
			if (RegionSearchManager.IsBeamCellFunctionOnPlane(level, lstBoundaryCvs, lstLanes, false))
			{
				regionLane = new RegionFuncInfo();
				regionLane.ERegionFunc = ERegionFunc.eLane;
				regionLane.SetCurves(lstBoundaryCvs);
				return true;
			}
			return false;
		}

		public static void ClearParkingRegionData()
		{
			RegionSearchManager.m_mapParkingSymbolName2Cvs.Clear();
		}

		private static List<double> GetParaDouble(FamilyInstance drant)
		{
			string paramName = "车位长";
			string paramName2 = "停车位宽度";
			List<double> list = new List<double>();
			double num = 0.0;
			double num2 = 0.0;
			Parameter parameter = drant.GetParameter(paramName);
			Parameter parameter2 = drant.GetParameter(paramName2);
			parameter = RegionSearchManager.GetSpecParameterByStr(drant.Parameters, "车位长");
			if (parameter == null)
			{
				parameter = RegionSearchManager.GetSpecParameterByStr(drant.Parameters, "长");
			}
			parameter2 = RegionSearchManager.GetSpecParameterByStr(drant.Parameters, "车位宽");
			if (parameter2 == null)
			{
				parameter2 = RegionSearchManager.GetSpecParameterByStr(drant.Parameters, "宽");
			}
			if (parameter == null || parameter2 == null)
			{
				ParameterSet parameters = drant.Symbol.Parameters;
				parameter = RegionSearchManager.GetSpecParameterByStr(parameters, "车位长");
				if (parameter == null)
				{
					parameter = RegionSearchManager.GetSpecParameterByStr(parameters, "长");
				}
				parameter2 = RegionSearchManager.GetSpecParameterByStr(parameters, "车位宽");
				if (parameter2 == null)
				{
					parameter2 = RegionSearchManager.GetSpecParameterByStr(parameters, "宽");
				}
				if (parameter != null && parameter2 != null)
				{
					num2 = parameter.AsDouble();
					num = parameter2.AsDouble();
				}
				if (num2 == 0.0 || num == 0.0)
				{
					string name = drant.Name;
					if (name.Contains("x"))
					{
						try
						{
							string[] array = name.Split(new char[]
							{
								'x'
							});
							num2 = double.Parse(array[0]) / 304.8;
							num = double.Parse(array[1]) / 304.8;
						}
						catch
						{
							num = 0.0;
							num2 = 0.0;
						}
					}
				}
			}
			list.Add(num2);
			list.Add(num);
			return list;
		}

		private static Parameter GetSpecParameterByStr(ParameterSet paramSet, string strValue)
		{
			Parameter result = null;
			foreach (object obj in paramSet)
			{
				Parameter parameter = (Parameter)obj;
				if (parameter.Definition.Name.Contains(strValue))
				{
					result = parameter;
				}
			}
			return result;
		}

		public static List<Curve> GetParkingSymbolCvs(FamilyInstance fiParking, ref double dWidth)
		{
			List<Curve> list = new List<Curve>();
			string name = fiParking.Symbol.Name;
			List<double> paraDouble = RegionSearchManager.GetParaDouble(fiParking);
			try
			{
				double num = paraDouble[0];
				dWidth = paraDouble[1];
				if (RegionSearchManager.m_mapParkingSymbolName2Cvs.ContainsKey(name))
				{
					list = RegionSearchManager.m_mapParkingSymbolName2Cvs[name];
				}
				else
				{
					XYZ xyz = XYZ.Zero - XYZ.BasisX * dWidth * 0.5;
					xyz += XYZ.BasisY * num * 0.5;
					XYZ xyz2 = xyz + XYZ.BasisX * dWidth;
					XYZ xyz3 = xyz2 - XYZ.BasisY * num;
					XYZ xyz4 = xyz - XYZ.BasisY * num;
					Curve item = Line.CreateBound(xyz, xyz2);
					Curve item2 = Line.CreateBound(xyz2, xyz3);
					Curve item3 = Line.CreateBound(xyz3, xyz4);
					Curve item4 = Line.CreateBound(xyz4, xyz);
					list.Add(item);
					list.Add(item2);
					list.Add(item3);
					list.Add(item4);
					RegionSearchManager.m_mapParkingSymbolName2Cvs.Add(name, list);
				}
			}
			catch (Exception ex)
			{
				ex.ToString();
			}
			return list;
		}

		public static bool IsBeamCellFuncParking(Level level, List<Curve> lstBoundaryCvs, List<FamilyInstance> lstParkings, ref RegionParkingInfo regionParking)
		{
			foreach (FamilyInstance familyInstance in lstParkings)
			{
				Transform mat = familyInstance.GetTotalTransform();
				double width = 0.0;
				List<Curve> parkingSymbolCvs = RegionSearchManager.GetParkingSymbolCvs(familyInstance, ref width);
				List<Curve> lstTransCvs = new List<Curve>();
				parkingSymbolCvs.ForEach(delegate(Curve e)
				{
					Curve item = e.CreateTransformed(mat);
					lstTransCvs.Add(item);
				});
				if (RegionSearchManager.IsBeamCellFunctionOnPlane(level, lstBoundaryCvs, lstTransCvs, true))
				{
					regionParking = new RegionParkingInfo();
					regionParking.ERegionFunc = ERegionFunc.eParking;
					regionParking.SetCurves(lstBoundaryCvs);
					regionParking.GeoPos = LightingEquipmentLay.Utility.Common.Centroid(lstBoundaryCvs);
					regionParking.Direction = mat.OfVector(XYZ.BasisX);
					regionParking.Width = width;
					return true;
				}
			}
			return false;
		}

		public static List<Curve> GetRoomBoundaryCvs(Room room)
		{
			List<Curve> list = new List<Curve>();
			if (room.Area <= 1E-06)
			{
				return list;
			}
			SpatialElementBoundaryOptions spatialElementBoundaryOptions = new SpatialElementBoundaryOptions();
			IList<IList<BoundarySegment>> boundarySegments = room.GetBoundarySegments(spatialElementBoundaryOptions);
			List<BoundarySegment> list2 = null;
			if (boundarySegments.Count > 0)
			{
				list2 = boundarySegments.First<IList<BoundarySegment>>().ToList<BoundarySegment>();
			}
			if (list2 != null && list2.Count > 0)
			{
				foreach (BoundarySegment boundarySegment in list2)
				{
					if (boundarySegment != null)
					{
						list.Add(boundarySegment.GetCurve());
					}
				}
			}
			return list;
		}

		public static bool IsBeamCellFuncRoom(Level level, List<Curve> lstBoundaryCvs, List<Room> lstRooms, ref RegionFuncInfo regionRoom)
		{
			foreach (Room room in lstRooms)
			{
				List<Curve> roomBoundaryCvs = RegionSearchManager.GetRoomBoundaryCvs(room);
				if (RegionSearchManager.IsBeamCellFunctionOnPlane(level, lstBoundaryCvs, roomBoundaryCvs, true))
				{
					regionRoom = new RegionFuncInfo();
					regionRoom.ERegionFunc = ERegionFunc.eRoom;
					regionRoom.SetCurves(lstBoundaryCvs);
					return true;
				}
			}
			return false;
		}

		public static List<RegionFuncInfo> GetDocBeamCellFuncInfos(UIDocument uiDoc, Level level, List<CurveLoop> loopCvs, List<Curve> lstLanes, List<FamilyInstance> lstParkings, List<Room> lstRooms)
		{
			RegionSearchManager.ClearParkingRegionData();
			List<RegionFuncInfo> list = new List<RegionFuncInfo>();
			List<BeamRegionData> list2 = RegionBeamCellSplitor.SplitRegion(uiDoc, loopCvs, false);
			using (ProgressBarForm progressBarForm = new ProgressBarForm(list2.Count, ProgressBarStyle.Blocks, true))
			{
				WindowHandle owner = new WindowHandle(Process.GetCurrentProcess().MainWindowHandle);
				progressBarForm.Text = "正在进行梁格区域识别";
				progressBarForm.ShowInTaskbar = false;
				progressBarForm.Show(owner);
				foreach (BeamRegionData beamRegionData in list2)
				{
					progressBarForm.RefreshProgressBar();
					if (progressBarForm.m_stopTag)
					{
						break;
					}
					foreach (BeamCellData beamCellData in beamRegionData.m_arBeamCell)
					{
						List<Curve> list3 = new List<Curve>();
						foreach (Curve item in beamCellData.GetCurveLoop())
						{
							list3.Add(item);
						}
						RegionFuncInfo item2 = null;
						if (RegionSearchManager.IsBeamCellFuncLane(level, list3, lstLanes, ref item2))
						{
							list.Add(item2);
						}
						else
						{
							RegionParkingInfo item3 = null;
							if (RegionSearchManager.IsBeamCellFuncParking(level, list3, lstParkings, ref item3))
							{
								list.Add(item3);
							}
							else
							{
								RegionFuncInfo item4 = null;
								if (RegionSearchManager.IsBeamCellFuncRoom(level, list3, lstRooms, ref item4))
								{
									list.Add(item4);
								}
								else
								{
									RegionFuncInfo regionFuncInfo = new RegionFuncInfo();
									regionFuncInfo.ERegionFunc = ERegionFunc.eOthers;
									regionFuncInfo.BoundaryCvs = new CurveArray();
									foreach (Curve curve in beamCellData.GetCurveLoop())
									{
										regionFuncInfo.BoundaryCvs.Append(curve);
									}
									list.Add(regionFuncInfo);
								}
							}
						}
					}
				}
			}
			return list;
		}

		public static List<RegionFuncInfo> GetDocFlatPlateFloorCellFuncInfos(Autodesk.Revit.DB.Document doc, Level level, List<FamilyInstance> lstColumns, List<Grid> lstGrids, List<Curve> lstLanes, List<FamilyInstance> lstParkings, List<Room> lstRooms, List<CurveLoop> loops)
		{
			List<RegionFuncInfo> list = new List<RegionFuncInfo>();
			RegionSearchManager.ClearParkingRegionData();
			List<List<Curve>> flatPlateFloorRegionCellsByDoc = FlatPlateFloorRegionCellsOper.GetFlatPlateFloorRegionCellsByDoc(doc, lstGrids, lstColumns, loops);
			using (ProgressBarForm progressBarForm = new ProgressBarForm(flatPlateFloorRegionCellsByDoc.Count, ProgressBarStyle.Blocks, true))
			{
				WindowHandle owner = new WindowHandle(Process.GetCurrentProcess().MainWindowHandle);
				progressBarForm.Text = "正在进行无梁楼盖区域识别";
				progressBarForm.Show(owner);
				foreach (List<Curve> list2 in flatPlateFloorRegionCellsByDoc)
				{
					progressBarForm.RefreshProgressBar();
					if (progressBarForm.m_stopTag)
					{
						break;
					}
					RegionFuncInfo item = null;
					if (RegionSearchManager.IsBeamCellFuncLane(level, list2, lstLanes, ref item))
					{
						list.Add(item);
					}
					else
					{
						RegionParkingInfo item2 = null;
						if (RegionSearchManager.IsBeamCellFuncParking(level, list2, lstParkings, ref item2))
						{
							list.Add(item2);
						}
						else
						{
							RegionFuncInfo item3 = null;
							if (RegionSearchManager.IsBeamCellFuncRoom(level, list2, lstRooms, ref item3))
							{
								list.Add(item3);
							}
							else
							{
								RegionFuncInfo regionFuncInfo = new RegionFuncInfo();
								regionFuncInfo.ERegionFunc = ERegionFunc.eOthers;
								regionFuncInfo.SetCurves(list2);
								list.Add(regionFuncInfo);
							}
						}
					}
				}
			}
			return list;
		}

		public static Plane CreatePlaneByLevel(Level level)
		{
			return UnifiedModified.CreatePlane(-XYZ.BasisZ, XYZ.Zero);
		}

		public static bool IsEqualLevel(Level level1, Level level2)
		{
			return Geometry.IsEqual(level1.ProjectElevation, level2.ProjectElevation);
		}

		private static Dictionary<string, List<Curve>> m_mapParkingSymbolName2Cvs = new Dictionary<string, List<Curve>>();

		public static string m_strExtendName = "车道线";

		public static string m_strLightLayStyle = "单";

		public static string[] arFunctionRegionName = new string[]
		{
			"车道线区域",
			"车位区域",
			"房间区域",
			"边角区域"
		};
	}
}
